home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Open via Map / Open via Map Source / Source / Open via Map Panel.c < prev    next >
Text File  |  2000-06-23  |  18KB  |  891 lines

  1. // Open via Map Panel.c
  2.  
  3. #include "Open via Map.h"
  4.  
  5. #include <MoreFilesExtras.h>
  6. #include <Search.h>
  7.  
  8. enum
  9. {
  10.     kMenuBarID        = 128,
  11.     
  12.     kAppleMenu        = 128,
  13.     kFileMenu        = 129,
  14.     kEditMenu        = 130,
  15.     
  16.     kAboutItem        = 1,
  17.     
  18.     kCloseItem        = 1,
  19.     kQuitItem        = 3,
  20.     
  21.     kUndoItem        = 1,
  22.     kCutItem        = 3,
  23.     kCopyItem        = 4,
  24.     kPasteItem        = 5,
  25.     kClearItem        = 6
  26. };
  27.  
  28. enum
  29. {
  30.     kMainDlogID            = 128,
  31.     kActiveItemID        = 1,
  32.     
  33.     kAboutDlogID        = 129,
  34.     kVersionItemID        = 5
  35. };
  36.  
  37. Boolean gQuit;
  38. Boolean gInBackground;
  39.  
  40. MenuHandle gAppleMenu;
  41. MenuHandle gFileMenu;
  42. MenuHandle gEditMenu;
  43.  
  44. Preferences gPreferences;
  45. Preferences gStartPreferences;
  46.  
  47. static Boolean IsSystemReady(void)
  48. {
  49.     OSStatus theStatus;
  50.     long theResponse;
  51.     Boolean isPresent;
  52.     
  53.     theStatus = Gestalt(gestaltAppearanceAttr, &theResponse);
  54.     
  55.     if (theStatus == noErr)
  56.         isPresent = theResponse & (1 << gestaltAppearanceExists);
  57.     
  58.     if ((theStatus == noErr) && isPresent)
  59.     {
  60.         theStatus = Gestalt(gestaltWindowMgrAttr, &theResponse);
  61.         
  62.         if (theStatus == noErr)
  63.             isPresent = theResponse & gestaltWindowMgrPresent;
  64.     }
  65.     
  66.     if (theStatus != noErr)
  67.         isPresent = false;
  68.     
  69.     return isPresent;
  70. }
  71.  
  72. static void Initialize(void)
  73. {
  74.     InitGraf(&qd.thePort);
  75.     InitFonts();
  76.     InitWindows();
  77.     InitMenus();
  78.     TEInit();
  79.     InitDialogs(NULL);
  80.     
  81.     MaxApplZone();
  82.     
  83.     if (IsSystemReady())
  84.         RegisterAppearanceClient();
  85.     else
  86.     {
  87.         SysBeep(0);
  88.         gQuit = true;
  89.     }
  90.     
  91.     FlushEvents(everyEvent, 0);
  92.     InitCursor();
  93. }
  94.  
  95. static void InstallMenus(void)
  96. {
  97.     Handle theMenuBar;
  98.     
  99.     theMenuBar = GetNewMBar(kMenuBarID);
  100.     
  101.     if (theMenuBar)
  102.     {
  103.         SetMenuBar(theMenuBar);
  104.         DisposeHandle(theMenuBar);
  105.         
  106.         gAppleMenu = GetMenuHandle(kAppleMenu);
  107.         gFileMenu = GetMenuHandle(kFileMenu);
  108.         gEditMenu = GetMenuHandle(kEditMenu);
  109.         
  110.         AppendResMenu(gAppleMenu, 'DRVR');
  111.         
  112.         DrawMenuBar();
  113.     }
  114. }
  115.  
  116. static OSErr GetPreferences(void)
  117. {
  118.     OSErr theErr;
  119.     FSSpec theSpec;
  120.     short refNum;
  121.     Preferences **thePreferences;
  122.     
  123.     gPreferences.theVersion = kPreferencesVersion;
  124.     gPreferences.isActive = true;
  125.     gPreferences.thePosition.top = 0;
  126.     gPreferences.thePosition.left = 0;
  127.     gPreferences.thePosition.bottom = 0;
  128.     gPreferences.thePosition.right = 0;
  129.     
  130.     theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  131.         &theSpec.vRefNum, &theSpec.parID);
  132.     
  133.     if (theErr == noErr)
  134.     {
  135.         GetIndString(theSpec.name, kPreferencesStrxID, kPrefNameIndex);
  136.         
  137.         refNum = FSpOpenResFile(&theSpec, fsRdPerm);
  138.         theErr = ResError();
  139.         
  140.         if (theErr == noErr)
  141.         {
  142.             thePreferences = (Preferences **) Get1Resource(kPreferencesType, kPreferencesID);
  143.             
  144.             if (thePreferences && ((**thePreferences).theVersion == kPreferencesVersion))
  145.                 gPreferences = **thePreferences;
  146.             
  147.             CloseResFile(refNum);
  148.         }
  149.     }
  150.     
  151.     gStartPreferences = gPreferences;
  152.     
  153.     return theErr;
  154. }
  155.  
  156. static OSErr SavePreferences(void)
  157. {
  158.     OSErr theErr;
  159.     OSStatus theStatus;
  160.     short refNum;
  161.     WindowPtr theWindow;
  162.     FSSpec theSpec;
  163.     Preferences **thePreferences;
  164.     
  165.     theWindow = FrontWindow();
  166.     
  167.     theStatus = GetWindowBounds(theWindow, kWindowStructureRgn, &gPreferences.thePosition);
  168.     
  169.     if (theStatus != noErr)
  170.     {
  171.         gPreferences.thePosition.top = 0;
  172.         gPreferences.thePosition.left = 0;
  173.         gPreferences.thePosition.bottom = 0;
  174.         gPreferences.thePosition.right = 0;
  175.     }
  176.     
  177.     if ((gPreferences.theVersion != gStartPreferences.theVersion) ||
  178.         (gPreferences.isActive != gStartPreferences.isActive) ||
  179.         (gPreferences.thePosition.top != gStartPreferences.thePosition.top) ||
  180.         (gPreferences.thePosition.left != gStartPreferences.thePosition.left))
  181.     {
  182.         theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
  183.             &theSpec.vRefNum, &theSpec.parID);
  184.     }
  185.     else
  186.     {
  187.         // The preferences are the same, so don't write them out
  188.         // The easiest way to do this is to just set the error flag here
  189.         theErr = 1;
  190.     }
  191.     
  192.     if (theErr == noErr)
  193.     {
  194.         GetIndString(theSpec.name, kPreferencesStrxID, kPrefNameIndex);
  195.         
  196.         refNum = FSpOpenResFile(&theSpec, fsRdWrPerm);
  197.         theErr = ResError();
  198.         
  199.         if (theErr == fnfErr)
  200.         {
  201.             FSpCreateResFile(&theSpec, kOpenViaMapPanelCode, kPreferencesType, smSystemScript);
  202.             theErr = ResError();
  203.             
  204.             if (theErr == noErr)
  205.             {
  206.                 refNum = FSpOpenResFile(&theSpec, fsRdWrPerm);
  207.                 theErr = ResError();
  208.             }
  209.         }
  210.         
  211.         if (theErr == noErr)
  212.         {
  213.             thePreferences = (Preferences **) Get1Resource(kPreferencesType, kPreferencesID);
  214.             
  215.             if (thePreferences)
  216.             {
  217.                 RemoveResource((Handle) thePreferences);
  218.                 theErr = ResError();
  219.                 
  220.                 if (theErr == noErr)
  221.                 {
  222.                     DisposeHandle((Handle) thePreferences);
  223.                     
  224.                     UpdateResFile(refNum);
  225.                     theErr = ResError();
  226.                 }
  227.             }
  228.             
  229.             thePreferences = (Preferences **) NewHandle(sizeof(gPreferences));
  230.             
  231.             if (thePreferences)
  232.             {
  233.                 **thePreferences = gPreferences;
  234.                 AddResource((Handle) thePreferences, kPreferencesType, kPreferencesID, NULL);
  235.                 theErr = ResError();
  236.                 
  237.                 UpdateResFile(refNum);
  238.                 theErr = ResError();
  239.             }
  240.             
  241.             CloseResFile(refNum);
  242.         }
  243.     }
  244.     
  245.     gStartPreferences = gPreferences;
  246.     
  247.     return theErr;
  248. }
  249.  
  250. static Boolean FindActiveProcessID(OSType theCreator, ProcessSerialNumber *thePSN)
  251. {
  252.     Boolean isFound;
  253.     ProcessInfoRec theInfo;
  254.     FSSpec theProcessSpec;
  255.     Str31 theName;
  256.     
  257.     isFound = false;
  258.     
  259.     thePSN->highLongOfPSN = 0;
  260.     thePSN->lowLongOfPSN = kNoProcess;
  261.     
  262.     while ((!isFound) && (GetNextProcess(thePSN) == noErr))
  263.     {
  264.         theInfo.processInfoLength = sizeof(theInfo);
  265.         theInfo.processName = (StringPtr) &theName;
  266.         theInfo.processAppSpec = &theProcessSpec;
  267.         
  268.         if (GetProcessInformation(thePSN, &theInfo) == noErr)
  269.         {
  270.             if (theCreator == theInfo.processSignature)
  271.                 isFound = true;
  272.         }
  273.     }
  274.     
  275.     if (!isFound)
  276.     {
  277.         thePSN->highLongOfPSN = 0;
  278.         thePSN->lowLongOfPSN = kNoProcess;
  279.     }
  280.     
  281.     return isFound;
  282. }
  283.  
  284. static OSErr QuitBackground(void)
  285. {
  286.     OSErr theErr;
  287.     AEAddressDesc theTarget;
  288.     AppleEvent theEvent;
  289.     ProcessSerialNumber thePSN;
  290.     
  291.     FindActiveProcessID(kOpenViaMapExtensionCode, &thePSN);
  292.     
  293.     theErr = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &theTarget);
  294.     
  295.     if (theErr == noErr)
  296.     {
  297.         theErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theTarget,
  298.             kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  299.         
  300.         AEDisposeDesc(&theTarget);
  301.         
  302.         if (theErr == noErr)
  303.         {
  304.             theErr = AESend(&theEvent, NULL, kAENoReply + kAECanInteract,
  305.                 kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  306.             
  307.             AEDisposeDesc(&theEvent);
  308.         }
  309.     }
  310.     
  311.     return theErr;
  312. }
  313.  
  314. static OSErr ChangeActiveBackground(Boolean isActive)
  315. {
  316.     OSErr theErr;
  317.     AEAddressDesc theTarget;
  318.     AppleEvent theEvent;
  319.     ProcessSerialNumber thePSN;
  320.     
  321.     FindActiveProcessID(kOpenViaMapExtensionCode, &thePSN);
  322.     
  323.     theErr = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &theTarget);
  324.     
  325.     if (theErr == noErr)
  326.     {
  327.         theErr = AECreateAppleEvent(kOpenViaMapEventClass, kActiveChange, &theTarget,
  328.             kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  329.         
  330.         AEDisposeDesc(&theTarget);
  331.         
  332.         if (theErr == noErr)
  333.         {
  334.             theErr = AEPutParamPtr(&theEvent, keyDirectObject, typeBoolean, &isActive,
  335.                 sizeof(isActive));
  336.             
  337.             if (theErr == noErr)
  338.                 theErr = AESend(&theEvent, NULL, kAENoReply + kAECanInteract,
  339.                     kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  340.             
  341.             AEDisposeDesc(&theEvent);
  342.         }
  343.     }
  344.     
  345.     return theErr;
  346. }
  347.  
  348. static OSErr FindBackground(FSSpec *theSpec)
  349. {
  350.     OSErr theErr;
  351.     short theRealVRefNum;
  352.     long theMatchCount;
  353.     
  354.     theErr = DetermineVRefNum(NULL, 0, &theRealVRefNum);
  355.     
  356.     if (theErr == noErr)
  357.     {
  358.         theErr = CreatorTypeFileSearch(NULL, theRealVRefNum, kOpenViaMapExtensionCode,
  359.             kBackgroundAppCode, theSpec, 1, &theMatchCount, true);
  360.         
  361.         if ((theErr == noErr) || (theErr == eofErr))
  362.         {
  363.             if (theMatchCount <= 0)
  364.                 theErr = afpItemNotFound;
  365.         }
  366.     }
  367.     
  368.     return theErr;
  369. }
  370.  
  371. static OSErr StartBackground(void)
  372. {
  373.     OSErr theErr;
  374.     LaunchParamBlockRec pb;
  375.     FSSpec theAppSpec;
  376.     
  377.     theErr = FindBackground(&theAppSpec);
  378.     
  379.     if (theErr == noErr)
  380.     {
  381.         pb.launchBlockID = extendedBlock;
  382.         pb.launchEPBLength = extendedBlockLen;
  383.         pb.launchFileFlags = 0;
  384.         pb.launchControlFlags = launchContinue + launchNoFileFlags;
  385.         pb.launchAppSpec = &theAppSpec;
  386.         pb.launchAppParameters = NULL;
  387.         
  388.         theErr = LaunchApplication(&pb);
  389.     }
  390.     
  391.     return theErr;
  392. }
  393.  
  394. static OSErr ChangeActive(DialogPtr theDialog, Boolean isActive)
  395. {
  396.     OSErr theErr;
  397.     Boolean isRunning;
  398.     ControlHandle theControl;
  399.     ProcessSerialNumber thePSN;
  400.     
  401.     theErr = GetDialogItemAsControl(theDialog, kActiveItemID, &theControl);
  402.     
  403.     if (theErr == noErr)
  404.     {
  405.         isRunning = FindActiveProcessID(kOpenViaMapExtensionCode, &thePSN);
  406.         
  407.         gPreferences.isActive = isActive;
  408.         
  409.         SetControlValue(theControl, isActive);
  410.         
  411.         if (isRunning)
  412.             ChangeActiveBackground(isActive);
  413.         else
  414.         {
  415.             SavePreferences();
  416.             StartBackground();
  417.         }
  418.     }
  419.     
  420.     return theErr;
  421. }
  422.  
  423. static void SetupWindow(void)
  424. {
  425.     OSStatus theStatus;
  426.     DialogPtr theDialog;
  427.     
  428.     theDialog = GetNewDialog(kMainDlogID, NULL, (WindowPtr) -1);
  429.     
  430.     ChangeActive(theDialog, gPreferences.isActive);
  431.     
  432.     if (gPreferences.thePosition.top || gPreferences.thePosition.left ||
  433.         gPreferences.thePosition.bottom || gPreferences.thePosition.right)
  434.         theStatus = MoveWindowStructure(GetDialogWindow(theDialog),
  435.             gPreferences.thePosition.left, gPreferences.thePosition.top);
  436.     
  437.     theStatus = TransitionWindow(GetDialogWindow(theDialog), kWindowZoomTransitionEffect,
  438.         kWindowShowTransitionAction, NULL);
  439. }
  440.  
  441. static void DoAbout(void)
  442. {
  443.     OSErr theErr;
  444.     Boolean isDone;
  445.     DialogItemIndex itemHit;
  446.     DialogPtr theDialog;
  447.     Handle theVersion;
  448.     ControlHandle theControl;
  449.     
  450.     theDialog = GetNewDialog(kAboutDlogID, NULL, (WindowPtr) -1);
  451.     
  452.     if (theDialog)
  453.     {
  454.         theVersion = Get1Resource('vers', 1);
  455.         
  456.         if (theVersion)
  457.         {
  458.             theErr = GetDialogItemAsControl(theDialog, kVersionItemID, &theControl);
  459.             
  460.             if (theErr == noErr)
  461.             {
  462.                 HLock(theVersion);
  463.                 SetDialogItemText((Handle) theControl, (ConstStr255Param) ((*theVersion) + 6));
  464.             }
  465.             
  466.             ReleaseResource(theVersion);
  467.         }
  468.         
  469.         theErr = TransitionWindow(GetDialogWindow(theDialog), kWindowZoomTransitionEffect,
  470.             kWindowShowTransitionAction, NULL);
  471.         
  472.         isDone = false;
  473.         
  474.         while (!isDone)
  475.         {
  476.             ModalDialog(NULL, &itemHit);
  477.             
  478.             if (itemHit)
  479.                 isDone = true;
  480.         }
  481.         
  482.         theErr = TransitionWindow(GetDialogWindow(theDialog), kWindowZoomTransitionEffect,
  483.             kWindowHideTransitionAction, NULL);
  484.         
  485.         DisposeDialog(theDialog);
  486.     }
  487. }
  488.  
  489. static OSErr DoQuit(void)
  490. {
  491.     gQuit = true;
  492.     
  493.     return noErr;
  494. }
  495.  
  496. static OSErr GetTargetFromSelf(AEAddressDesc *theTarget)
  497. {
  498.     OSErr theErr;
  499.     ProcessSerialNumber thePSN;
  500.     
  501.     thePSN.highLongOfPSN = 0;
  502.     thePSN.lowLongOfPSN = kCurrentProcess;
  503.     
  504.     theErr = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), theTarget);
  505.     
  506.     return theErr;
  507. }
  508.  
  509. static OSErr DoSendQuit(void)
  510. {
  511.     OSErr theErr;
  512.     AEAddressDesc theTarget;
  513.     AppleEvent theEvent;
  514.     
  515.     theErr = GetTargetFromSelf(&theTarget);
  516.     
  517.     if (theErr == noErr)
  518.     {
  519.         theErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theTarget,
  520.             kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  521.         
  522.         AEDisposeDesc(&theTarget);
  523.         
  524.         if (theErr == noErr)
  525.         {
  526.             theErr = AESend(&theEvent, NULL, kAENoReply + kAECanInteract,
  527.                 kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  528.             
  529.             AEDisposeDesc(&theEvent);
  530.         }
  531.     }
  532.     
  533.     return theErr;
  534. }
  535.  
  536. static OSErr GotRequiredParams(AppleEvent *theEvent)
  537. {
  538.     OSErr theErr;
  539.     DescType theType;
  540.     Size theSize;
  541.     
  542.     theErr = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard, &theType,
  543.         NULL, 0, &theSize);
  544.     
  545.     if (theErr == errAEDescNotFound)
  546.         theErr = noErr;
  547.     else
  548.         theErr = errAEParamMissed;
  549.     
  550.     return theErr;
  551. }
  552.  
  553. static pascal OSErr DoHandleOpenApplication(AppleEvent *theEvent, AppleEvent *theReply,
  554.     UInt32 refCon)
  555. {
  556. #pragma unused(theReply, refCon)
  557.     OSErr theErr;
  558.     
  559.     theErr = GotRequiredParams(theEvent);
  560.     
  561.     return theErr;
  562. }
  563.  
  564. static pascal OSErr DoHandleOpenPrint(AppleEvent *theEvent, Boolean isOpen)
  565. {
  566. #pragma unused(isOpen)
  567.     OSErr theErr;
  568.     
  569.     theErr = GotRequiredParams(theEvent);
  570.     
  571.     return theErr;
  572. }
  573.  
  574. static pascal OSErr DoHandleOpenDocuments(AppleEvent *theEvent, AppleEvent *theReply,
  575.     UInt32 refCon)
  576. {
  577. #pragma unused(theReply, refCon)
  578.     OSErr theErr;
  579.     
  580.     theErr = DoHandleOpenPrint(theEvent, true);
  581.     
  582.     return theErr;
  583. }
  584.  
  585. static pascal OSErr DoHandlePrintDocuments(AppleEvent *theEvent, AppleEvent *theReply,
  586.     UInt32 refCon)
  587. {
  588. #pragma unused(theReply, refCon)
  589.     OSErr theErr;
  590.     
  591.     theErr = DoHandleOpenPrint(theEvent, false);
  592.     
  593.     return theErr;
  594. }
  595.  
  596. static pascal OSErr DoHandleQuit(AppleEvent *theEvent, AppleEvent *theReply, UInt32 refCon)
  597. {
  598. #pragma unused(theReply, refCon)
  599.     OSErr theErr;
  600.     
  601.     theErr = GotRequiredParams(theEvent);
  602.     
  603.     if (theErr == noErr)
  604.         theErr = DoQuit();
  605.     
  606.     return theErr;
  607. }
  608.  
  609. static void InstallEventHandlers(void)
  610. {
  611.     OSErr theErr;
  612.     
  613.     theErr = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  614.         NewAEEventHandlerProc(&DoHandleOpenApplication), 0, false);
  615.     
  616.     if (theErr == noErr)
  617.         theErr = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  618.             NewAEEventHandlerProc(&DoHandleOpenDocuments), 0, false);
  619.     
  620.     if (theErr == noErr)
  621.         theErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  622.             NewAEEventHandlerProc(&DoHandlePrintDocuments), 0, false);
  623.     
  624.     if (theErr == noErr)
  625.         theErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  626.             NewAEEventHandlerProc(&DoHandleQuit), 0, false);
  627. }
  628.  
  629. static void DoAppleMenu(short theMenuItem)
  630. {
  631.     Str255 theItemName;
  632.     
  633.     switch (theMenuItem)
  634.     {
  635.         case kAboutItem:
  636.             DoAbout();
  637.             break;
  638.         default:
  639.             GetMenuItemText(gAppleMenu, theMenuItem, theItemName);
  640.             OpenDeskAcc(theItemName);
  641.             break;
  642.     }
  643. }
  644.  
  645. static void DoFileMenu(short theMenuItem)
  646. {
  647.     switch (theMenuItem)
  648.     {
  649.         case kCloseItem:
  650.             DoSendQuit();
  651.             break;
  652.         case kQuitItem:
  653.             DoSendQuit();
  654.             break;
  655.     }
  656. }
  657.  
  658. static void DoEditMenu(short theMenuItem)
  659. {
  660. #pragma unused(theMenuItem)
  661. }
  662.  
  663. static void DoMenuCommand(UInt32 theMenuResult)
  664. {
  665.     short theMenuID;
  666.     short theMenuItem;
  667.     
  668.     theMenuID = HiWord(theMenuResult);
  669.     theMenuItem = LoWord(theMenuResult);
  670.     
  671.     switch (theMenuID)
  672.     {
  673.         case kAppleMenu:
  674.             DoAppleMenu(theMenuItem);
  675.             break;
  676.         case kFileMenu:
  677.             DoFileMenu(theMenuItem);
  678.             break;
  679.         case kEditMenu:
  680.             DoEditMenu(theMenuItem);
  681.             break;
  682.     }
  683.     
  684.     HiliteMenu(0);
  685. }
  686.  
  687. static void DoUpdate(WindowPtr theWindow)
  688. {
  689.     BeginUpdate(theWindow);
  690.     UpdateDialog(theWindow, theWindow->visRgn);
  691.     EndUpdate(theWindow);
  692. }
  693.  
  694. static void DoActivate(WindowPtr theWindow, Boolean isActivating)
  695. {
  696.     OSErr theErr;
  697.     ControlHandle theRoot;
  698.     
  699.     theErr = GetRootControl(theWindow, &theRoot);
  700.     
  701.     if (theErr == noErr)
  702.     {
  703.         if (isActivating)
  704.             theErr = ActivateControl(theRoot);
  705.         else
  706.             theErr = DeactivateControl(theRoot);
  707.     }
  708. }
  709.  
  710. static void DoContentClick(EventRecord *theEvent, WindowPtr theWindow)
  711. {
  712. #pragma unused(theWindow)
  713.     OSErr theErr;
  714.     Boolean wasHit;
  715.     SInt16 theValue;
  716.     DialogItemIndex theItem;
  717.     DialogPtr theDialog;
  718.     ControlHandle theControl;
  719.     
  720.     wasHit = DialogSelect(theEvent, &theDialog, &theItem);
  721.     
  722.     if (theItem == kActiveItemID)
  723.     {
  724.         theErr = GetDialogItemAsControl(theDialog, theItem, &theControl);
  725.         
  726.         if (theErr == noErr)
  727.         {
  728.             theValue = GetControlValue(theControl);
  729.             
  730.             theErr = ChangeActive(theDialog, !theValue);
  731.         }
  732.     }
  733. }
  734.  
  735. static void DoMouseDown(EventRecord *theEvent)
  736. {
  737.     short thePart;
  738.     WindowPtr theWindow;
  739.     
  740.     thePart = FindWindow(theEvent->where, &theWindow);
  741.     
  742.     switch (thePart)
  743.     {
  744.         case inMenuBar:
  745.             DoMenuCommand(MenuSelect(theEvent->where));
  746.             break;
  747.         case inSysWindow:
  748.             SystemClick(theEvent, theWindow);
  749.             break;
  750.         case inContent:
  751.             DoContentClick(theEvent, theWindow);
  752.             break;
  753.         case inDrag:
  754.             DragWindow(theWindow, theEvent->where, &(**GetGrayRgn()).rgnBBox);
  755.             break;
  756.         case inGrow:
  757.             break;
  758.         case inGoAway:
  759.             if (TrackGoAway(theWindow, theEvent->where))
  760.                 DoSendQuit();
  761.             break;
  762.         case inZoomIn:
  763.         case inZoomOut:
  764.             break;
  765.     }
  766. }
  767.  
  768. static void DoKeyDown(EventRecord *theEvent)
  769. {
  770.     char theKey;
  771.     
  772.     theKey = theEvent->message & charCodeMask;
  773.     
  774.     if (theEvent->modifiers & cmdKey)
  775.     {
  776.         DoMenuCommand(MenuEvent(theEvent));
  777.     }
  778. }
  779.  
  780. static void DoDiskEvent(EventRecord *theEvent)
  781. {
  782.     OSErr theErr;
  783.     Point thePoint;
  784.     
  785.     if (HiWord(theEvent->message) != noErr)
  786.     {
  787.         DILoad();
  788.         SetPt(&thePoint, 120, 120);
  789.         theErr = DIBadMount(thePoint, theEvent->message);
  790.         DIUnload();
  791.     }
  792. }
  793.  
  794. static void DoSuspendResumeEvent(EventRecord *theEvent)
  795. {
  796.     if (theEvent->message & resumeFlag)
  797.         gInBackground = false;
  798.     else
  799.         gInBackground = true;
  800.     
  801.     DoActivate(FrontWindow(), !gInBackground);
  802. }
  803.  
  804. static void DoOSEvent(EventRecord *theEvent)
  805. {
  806.     if (((theEvent->message & osEvtMessageMask) >> 24) == suspendResumeMessage)
  807.         DoSuspendResumeEvent(theEvent);
  808. }
  809.  
  810. static void DoHighLevelEvent(EventRecord *theEvent)
  811. {
  812.     OSErr theErr;
  813.     
  814.     theErr = AEProcessAppleEvent(theEvent);
  815. }
  816.  
  817. static void DoEvent(EventRecord *theEvent)
  818. {
  819.     switch (theEvent->what)
  820.     {
  821.         case mouseDown:
  822.             DoMouseDown(theEvent);
  823.             break;
  824.         case keyDown:
  825.         case autoKey:
  826.             DoKeyDown(theEvent);
  827.             break;
  828.         case activateEvt:
  829.             DoActivate((WindowPtr) theEvent->message, theEvent->modifiers & activeFlag);
  830.             break;
  831.         case updateEvt:
  832.             DoUpdate((WindowPtr) theEvent->message);
  833.             break;
  834.         case diskEvt:
  835.             DoDiskEvent(theEvent);
  836.             break;
  837.         case osEvt:
  838.             DoOSEvent(theEvent);
  839.             break;
  840.         case kHighLevelEvent:
  841.             DoHighLevelEvent(theEvent);
  842.             break;
  843.     }
  844. }
  845.  
  846. static void DoIdle(EventRecord *theEvent)
  847. {
  848. #pragma unused(theEvent)
  849. }
  850.  
  851. static void MainEventLoop(void)
  852. {
  853.     Boolean gotEvent;
  854.     UInt32 theSleep;
  855.     EventRecord theEvent;
  856.     
  857.     theSleep = GetCaretTime();
  858.     
  859.     while (!gQuit)
  860.     {
  861.         gotEvent = WaitNextEvent(everyEvent, &theEvent, theSleep, NULL);
  862.         
  863.         if (gotEvent)
  864.             DoEvent(&theEvent);
  865.         else
  866.             DoIdle(&theEvent);
  867.     }
  868. }
  869.  
  870. void main(void)
  871. {
  872.     gQuit = false;
  873.     gInBackground = false;
  874.     
  875.     Initialize();
  876.     
  877.     if (!gQuit)
  878.     {
  879.         InstallEventHandlers();
  880.         InstallMenus();
  881.         GetPreferences();
  882.         SetupWindow();
  883.         
  884.         MainEventLoop();
  885.         
  886.         TransitionWindow(FrontWindow(), kWindowZoomTransitionEffect, kWindowHideTransitionAction,
  887.             NULL);
  888.         
  889.         SavePreferences();
  890.     }
  891. }